package com.shouxin.attendance.service;

import android.os.Handler;
import android.os.HandlerThread;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.shouxin.attendance.constants.PrefKey;
import com.shouxin.attendance.database.DBHelper;
import com.shouxin.attendance.database.model.PushData;
import com.shouxin.attendance.network.CommonCallback;
import com.shouxin.attendance.network.HttpAction;
import com.shouxin.attendance.network.ServiceFactory;
import com.shouxin.attendance.utils.SharedPref;
import com.shouxin.attendance.utils.Utils;

import org.apache.log4j.Logger;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Response;

/**
 * 用来上传刷卡信息：上车/下车
 */
public class BackgroundService {

	private static final Logger logger = Logger.getLogger(BackgroundService.class);

    private final static long TIME_DELAY = 1000;

    private static final long HEART_BEAT_DELAY = 5 * 60 * 1000;

	private LinkedBlockingQueue<PushData> mLinkedQueue = new LinkedBlockingQueue<>();

	private HandlerThread mThread;

	//private HandlerThread mHeartThread;

    private BackgroundService() {
        startThread();
    }

	public static BackgroundService getInstance() {
		return Instance.instance;
	}

	private void startThread() {
		mThread = new HandlerThread("BackgroundService-Thread");
		mThread.start();
		Handler handler = new Handler(mThread.getLooper());
		handler.post(new Runnable() {
			@Override
			public void run() {
				initLocalPushData();
				doPushData();
			}
		});

        /*mHeartThread = new HandlerThread("BackgroundHeartService-Thread");
        mHeartThread.start();
        Handler heartHandler = new Handler(mHeartThread.getLooper());
        heartHandler.post(new Runnable() {
            @Override
            public void run() {
                doHeart();
            }
        });*/
    }

    private void doHeart() {
        while (true) {
            HttpAction httpAction = ServiceFactory.get().getService(HttpAction.NAME);
            if (httpAction == null) {
	            logger.error("HttpAction is null");
	            return;
            }
	        logger.debug("正在发生心跳...");
	        try {
                HashMap<String, String> requestParams = new HashMap<>();
                requestParams.put("ver", Utils.getAppVersionName());
                requestParams.put("client", "1");
                httpAction.heartBeat(requestParams, this);

	            TimeUnit.MILLISECONDS.sleep(HEART_BEAT_DELAY);
	        } catch (Exception e) {
		        logger.debug("心跳发送异常...");
	        }
        }
    }

	public void networkConnected(boolean isConnected) {
		logger.debug("networkConnected =>" + isConnected);
		boolean isLogin = SharedPref.getBoolean(PrefKey.HAS_LOGGED, false);
		if (isLogin) {
			if (isConnected) {
				if (mThread != null) {
					mThread.quit();
					mThread = null;
				}
				//mHeartThread.quit();
				startThread();
            } else {
				if (mThread != null) {
					mThread.quit();
					mThread = null;
				}
				//mHeartThread.quit();
			}
        } else {
			logger.debug("App not login!");
		}
	}

	public void initLocalPushData() {
		try {
			// 先清空数据
			mLinkedQueue.clear();

			List<PushData> dataList = DBHelper.getInstance().getPushDataDao().queryBuilder().list();
			logger.debug("PushData list =>" + dataList.size());
			if (dataList.isEmpty()) {
				return;
			}
			for (PushData data : dataList) {
				addPushData(data);
			}
		} catch (Exception e) {
			logger.error("initLocalPushData exception =>", e);
		}
	}

	public void addPushData(PushData data) {
		if (data == null) {
			logger.error("addPushData:data is null!");
			return;
		}
		try {
			logger.debug("addPushData =>" + data);
			DBHelper.getInstance().getPushDataDao().insertOrReplace(data);
			mLinkedQueue.put(data);
		} catch (Exception e) {
			logger.error("addPushData exception =>", e);
		}
	}

	private void doPushData() {
		while (true) {
			try {
				if (mLinkedQueue.isEmpty()) {
					logger.debug("No offline data need push to server.");
				}
				final PushData data = mLinkedQueue.take();

				logger.debug("start request push data...");
				JSONObject requestParams = new JSONObject();
                requestParams.put("ver", Utils.getAppVersionName());
                requestParams.put("token", SharedPref.getString(PrefKey.TOKEN, ""));
                requestParams.put("card", data.getBaby().getCard());
                requestParams.put("baby_id", data.getBaby().getId());
                requestParams.put("sign_time", data.getSendTime());
                requestParams.put("status", data.getStatus());
				requestParams.put("exception", data.getExceptionCode());
				logger.debug("request body =>" + requestParams);

				HttpAction httpAction = ServiceFactory.get().getService(HttpAction.NAME);
				if (httpAction == null) {
					logger.debug("HttpAction is null");
					return;
				}
				httpAction.swipeCard(requestParams.toJSONString(), this, new CommonCallback() {
					@Override
					public void onResponse(Call call, Response response) throws IOException {
						try {
							JSONObject object = JSON.parseObject(response.body().string());
							logger.error("doPushData:response = " + object);
							DBHelper.getInstance().getPushDataDao().delete(data);
							int ret = object.getIntValue("ret");
							if (ret != 0) {
								logger.debug("ret = " + ret + "--" + object.getString("msg"));
							}
						} catch (Exception e) {
							logger.error("json parser error", e);
						}
					}

					@Override
					public void onFailure(Call call, IOException e) {
						super.onFailure(call, e);
						addPushData(data);
					}
				});

				TimeUnit.MILLISECONDS.sleep(TIME_DELAY);
			} catch (Exception e) {
				logger.error("PushDataRunnable exception =>", e);
			}
		}
	}

	private static class Instance {

		private static BackgroundService instance = new BackgroundService();
	}

}
